﻿@using Xunit;
@inherits TestContext
@code
{
    public FluentRatingTests()
    {
        JSInterop.Mode = JSRuntimeMode.Loose;
        Services.AddSingleton(new LibraryConfiguration());
    }

    [Fact]
    public void FluentRating_Empty()
    {
        // Arrange && Act
        var cut = Render(@<FluentRating />);

        // Assert
        cut.Verify();
    }

    [Fact]
    public void FluentRating_Label()
    {
        // Arrange && Act
        var cut = Render(@<FluentRating Label="My Label" />);

        // Assert
        cut.Verify();
    }

    [Fact]
    public void FluentRating_LabelTemplate()
    {
        // Arrange && Act
        var cut = Render(@<FluentRating><LabelTemplate>My <b>Label</b> Template</LabelTemplate></FluentRating>);

        // Assert
        cut.Verify();
    }

    [Fact]
    public void FluentRating_Value()
    {
        // Arrange && Act
        var cut = Render(@<FluentRating Max="10" Value="2" />);

        // Assert
        cut.Verify();
    }

    [Fact]
    public void FluentRating_SelectValue()
    {
        int value = 0;

        // Arrange
        var cut = Render(@<FluentRating @bind-Value="@value" />);

        // Act: Click on the second star
        cut.FindAll("svg").ElementAt(1).Click();

        // Assert
        Assert.Equal(2, value);
    }

    [Fact]
    public void FluentRating_FocusOnRadio()
    {
        int value = 0;

        // Arrange
        var cut = Render(@<FluentRating @bind-Value="@value" />);

        // Act: Focus on the second star
        cut.FindAll("input").ElementAt(1).Focus();

        // Assert
        Assert.Equal(2, value);
    }

    [Fact]
    public void FluentRating_AllowResetFalse()
    {
        // Arrange
        int value = 0;
        var cut = Render(@<FluentRating @bind-Value="@value" AllowReset="false" />);

        // Act: Click twice on the second star
        cut.FindAll("svg").ElementAt(1).Click();
        cut.FindAll("svg").ElementAt(1).Click();

        // Assert
        Assert.Equal(2, value);
    }

    [Fact]
    public void FluentRating_AllowResetTrue()
    {
        // Arrange
        int value = 0;
        var cut = Render(@<FluentRating @bind-Value="@value" AllowReset="true" />);

        // Act: Click twice on the second star
        cut.FindAll("svg").ElementAt(1).Click();
        cut.FindAll("svg").ElementAt(1).Click();

        // Assert
        Assert.Equal(0, value);
    }

    [Fact]
    public void FluentRating_Disabled()
    {
        int value = 3;
        // Arrange
        var cut = Render(@<FluentRating @bind-Value="@value" Disabled="true" />);

        // Act: Click on the second star
        cut.FindAll("svg").ElementAt(1).Click();

        // Assert
        Assert.Equal(3, value);
    }

    [Fact]
    public void FluentRating_ReadOnly()
    {
        // Arrange
        int value = 3;
        var cut = Render(@<FluentRating @bind-Value="@value" ReadOnly="true" />   );

        // Act: Click on the second star
        cut.FindAll("svg").ElementAt(1).Click();

        // Assert
        Assert.Equal(3, value);
    }

    [Fact]
    public async Task FluentRating_Hover()
    {
        // Arrange
        int value = 0;
        int? hover = null;
        var cut = Render(@<FluentRating OnHoverValueChanged="@(i => hover = i)" @bind-Value="@value" />);

        // Act
        var item = cut.FindAll("svg").ElementAt(3);
        await item.TriggerEventAsync("onmouseenter", new MouseEventArgs());

        // Assert
        Assert.Equal(0, value);
        Assert.Equal(4, hover);
    }

    [Fact]
    public async Task FluentRating_HoverMultiple()
    {
        // Arrange
        int value = 0;
        int? hover = null;
        var cut = Render(@<FluentRating OnHoverValueChanged="@(i => hover = i)" @bind-Value="@value" />);

        // Enter on the 4th star
        var item4 = cut.FindAll("svg").ElementAt(3);
        await item4.TriggerEventAsync("onmouseenter", new MouseEventArgs());

        Assert.Equal(4, hover);

        // Enter on the 3rd star
        var item3 = cut.FindAll("svg").ElementAt(2);
        await item3.TriggerEventAsync("onmouseenter", new MouseEventArgs());

        Assert.Equal(3, hover);

        // Leave the 3rd star
        await item3.TriggerEventAsync("onmouseleave", new MouseEventArgs());

        Assert.Equal(0, value);
    }

    [Fact]
    public async Task FluentRating_HoverAndLeave()
    {
        // Arrange
        int value = 0;
        int? hover = null;
        var cut = Render(@<FluentRating OnHoverValueChanged="@(i => hover = i)" @bind-Value="@value" />);

        // Act: Hover
        var item = cut.FindAll("svg").ElementAt(3);
        await item.TriggerEventAsync("onmouseenter", new MouseEventArgs());

        Assert.Equal(4, hover);

        // Act: Leave
        var rating = cut.Find("div");
        await rating.TriggerEventAsync("onmouseleave", new MouseEventArgs());

        Assert.Null(hover);
    }
}
